var Q = require('q'),
    _ = require('lodash'),
    mongoose = require('mongoose'),
    barcodeMasterController = require('../../../Barcode/server/controllers/BarcodeMaster.server.controller'),
    PublicEnum = require('../../../Base/server/controllers/Enum'),
    Transaction = require('../../../Base/server/controllers/Transaction'),
    assemblyRelationController = require('../../../Barcode/server/controllers/AssemblyRelation.server.controller'),
    MOController = require('../../../ProduceReady/server/controllers/MO.server.contorller'),
    departmentController = require('../../../CBO/server/controllers/Department.server.controller'),
    stationWorkController = require('../../../Initialize/server/controllers/StationWork.server.controller'),
    operationController = require('../../../CBO/server/controllers/Operation.server.controller'),
    entityCollection = require('../../../Base/server/controllers/EntityCollection'),
    worklocationController = require('../../../CBO/server/controllers/WorkLocation.server.controller'),
    rcvRecordController = require('../../../ProduceWork/server/controllers/RcvRecord.server.controller'),

    completePlanController = require('../../../ProduceWork/server/controllers/CompletePlan.server.controllers');

//从完工计划表中获取批次
exports.getMOLotNumber = function (req, res) {
    completePlanController.queryAllCompletePlan(function (err, records) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        res.json({
            Data: records,
            Error: null
        });
    });
};

//获取工单
exports.getAllMOInfo = function (req, res) {
    MOController.getAllMOInfo(function (err, records) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        res.json({
            Data: records,
            Error: null
        });
    });
};


//批次绑定
exports.MOLotNumberToAssemblyBarcode = function (req, res) {
    var parameter = req.body.Parameter,
        Barcode = parameter.Barcode,
        SecurityId = parameter.SecurityId,
        lotNum = parameter.lotNum,
        Size = parameter.Size,
        appearance = parameter.appearance,
        completePlan = parameter.CompletePlan;

    if (!parameter.SecurityId) {
        barcodeMasterController.updateByValue(Barcode, {
            ShipLotNumber: lotNum,
            DescSeg1: Size,
            DescSeg2: appearance,
            CompletePlan: completePlan
        }, function (err, results) {
            if (err) {
                res.json({
                    Data: null,
                    Error: err
                });
                return;
            }
            res.json({
                Data: results,
                Error: null
            });
        });
    } else {
        var barcodeMasterData = {
            Barcode: SecurityId,
            BarcodeType: 0,
            IsAssembly: true
            //外部条码标识待定
            //todo
        };

        findLenCodeMaster(barcodeMasterData).then(function (barcodeMasterRecord) {
            findOneBarcodeMaster(Barcode).then(function (result) {
                assemblyRelationController.insertIfNotExist({
                    BarcodeMaster: result._id,
                    AssemblyBarcode: barcodeMasterRecord._id,
                    AssemblyType: 0
                }).then(function (assemblyRelationRecord) {
                    barcodeMasterController.updateByValue(Barcode, {
                        ShipLotNumber: lotNum,
                        DescSeg1: Size,
                        DescSeg2: appearance,
                        CompletePlan: completePlan
                    }, function (err, results) {
                        if (err) {
                            res.json({
                                Data: null,
                                Error: err
                            });
                        } else {
                            res.json({
                                Data: results,
                                Error: null
                            });
                        }
                    });
                }, function (err) {
                    res.json({
                        Data: null,
                        Error: err
                    });
                });
            }, function (err) {
                res.json({
                    Data: null,
                    Error: err
                });
            });
        }, function (err) {
            res.json({
                Data: null,
                Error: err
            });
        });
    }
};

function findLenCodeMaster (lenCodeData) {
    var deferred = Q.defer();

    findOneBarcodeMaster(lenCodeData.Barcode).then(function (lencodeMaster) {
        if (lencodeMaster) {
            deferred.resolve(lencodeMaster);
            return;
        }
        barcodeMasterController.createBarcodeMaster(lenCodeData, function (err, record) {
            if (err) {
                deferred.reject(err);
                return;
            }
            deferred.resolve(record);
        });
    }, function (err) {
        deferred.reject(err);
    });

    return deferred.promise;
}

//查询某一个主档信息
function findOneBarcodeMaster(barcode) {
    var deferred = Q.defer();
    barcodeMasterController.findAssemblyBarcodeMasterId(barcode, function (err, result) {
        if (err) {
            deferred.reject(err);
        } else {
            deferred.resolve(result)
        }
    });
    return deferred.promise;
}

/**
 * 根据条码(芯片ID)查找主档信息
 */
exports.findBarcodeMasterByBarcode = function (req, res) {
    var parameter = req.body.Parameter,
        barcode = parameter.Barcode;

    barcodeMasterController.findBarcodeMasterByBarcode(barcode, function (err, barcodeMasterRecord) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        res.json({
            Data: barcodeMasterRecord,
            Error: null
        });
    });
};

/**
 * 根据条码主档ID查找装配关系
 * @param req
 * @param res
 */
exports.findAssemblyRelationsByBarcodeMaster = function (req, res) {
    var parameter = req.body.Parameter,
        barcodeMasterId = parameter.barcodeMasterId;
    assemblyRelationController.findAssemblyRelationsByBarcodeMaster(barcodeMasterId, function (err, record) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        res.json({
            Data: record,
            Error: null
        });
    });
};

/**
 * 获取部门信息
 * @param req
 * @param res
 */
exports.queryDepartment = function (req, res) {
    var parameter = req.body,
        parentDepartment = parameter.parentDepartment;
    if (!parentDepartment) {//获取所有部门
        departmentController.getAllDepartment(function (err, records) {
            if (err) {
                res.json({
                    Data: null,
                    Error: err
                });
                return;
            }
            var departArr = [];
            _.forEach(records, function (record) {
                departArr.push(record._id);
            });
            getDepartmentByParentDepartment(departArr).then(function (results) {
                var obj = {};
                _.forEach(results, function (result) {
                    if (!obj[result.ParentDepartment.Name]) {
                        obj[result.ParentDepartment.Name] = [];
                    }
                    obj[result.ParentDepartment.Name].push({
                        id: result._id,
                        parentDepartment: result.ParentDepartment.Name,
                        department: result.Name
                    });
                });
                res.json({
                    Data: obj,
                    Error: null
                });
            }, function (err) {
                res.json({
                    Data: null,
                    Error: err
                });
            });

        });
    } else {//根据上级部门获取部门
        getDepartmentByParentDepartment(parentDepartment).then(function (records) {
            res.json({
                Data: records,
                Error: null
            });
        }, function (err) {
            res.json({
                Data: null,
                Error: err
            });
        });
    }

};

/**
 * 查找部门(一个或多个)下所有工位
 * @param req
 * @param res
 */
exports.queryWorkLocationByDepartment = function (req, res) {
    var parameter = req.body,
        departments = parameter.departments;
    worklocationController.findByDepartment(departments, function (err, records) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        res.json({
            Data: records,
            Error: null
        });
    });

};

/**
 *
 * @param req
 * @param res
 */
exports.countProductView = function (req, res) {
    var parameter = req.body,
        workLocations = parameter.workLocations,
        flg = parameter.flg,
        startTime = parameter.startTime,
        endTime = parameter.endTime,
        locationArr = [];
    _.forEach(workLocations, function (workLocation) {
        locationArr.push(mongoose.Types.ObjectId(workLocation));
    });

    var durationTime = convertTime(startTime, endTime);
    Q.all([getCompleteCount(flg, locationArr, durationTime.start, durationTime.end),
        getTotalCount(flg, locationArr, durationTime.start, durationTime.end)
    ]).then(function (ar) {
        var complete = ar[0],
            total = ar[1];
        res.json({
            Data: {
                complete: complete,
                total: total
            },
            Error: null
        });
    });

};

function convertTime (startTime, endTime) {
    var startTimeSplit = startTime.split(':'),
        endTimeSplit = endTime.split(':'),
        startTimes = [],
        endTimes = [],
        nowDate = new Date();
    for (var i = 0; i < 3; i++) {
        if (i > startTimeSplit.length - 1) {
            startTimes[i] = 0;
        } else {
            startTimes[i] = parseInt(startTimeSplit[i]) || 0;
        }
        if (i > endTimeSplit.length - 1) {
            endTimes[i] = 0;
        } else {
            endTimes[i] = parseInt(endTimeSplit[i]) || 0;
        }
    }
    var startDateTime = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), 
        startTimes[0], startTimes[1], startTimes[2]);
    var endDateTime;
    if (startTimes[0] * 3600 + startTimes[1] * 60 + startTimes[2] >= 
        endTimes[0] * 3600 + endTimes[1] * 60 + endTimes[2]
    ) {
        endDateTime = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate() + 1, 
            endTimes[0], endTimes[1], endTimes[2]);
    } else {
        endDateTime = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(),
            endTimes[0], endTimes[1], endTimes[2]);
    }
    return {
        start: startDateTime,
        end: endDateTime
    };
}

function getCompleteCount(flg, locationArr, startTime, endTime) {
    var deferred = Q.defer();
    
    var entity = entityCollection.getEntity("BizRecord");
    operationController.findCountPoint(function (err, array) {
        if (err) {
            deferred.reject(err);
            return;
        }
        var args = [];
        args.push({
            $match: {
                CreatedOn: {$gt: startTime, $lte: endTime},
                Operation: {$in: array},
                WorkLocation: {$in: locationArr}
            }
        });
        args.push({$sort: {CreatedOn: 1}});
        args.push({$group: {_id: {BarcodeMaster: "$BarcodeMaster", WorkLocation: "$WorkLocation"}, count: {$sum: 1}}});
        args.push({
            $project: {
                BarcodeMaster: "$_id.BarcodeMaster",
                WorkLocation: "$_id.WorkLocation",
                count: 1,
                _id: 0
            }
        });
        entity.aggregate(args, function (er, data) {
            if (er) {
                deferred.reject(er);
                return;
            }
            if (data.length === 0) {
                deferred.resolve({});
                return;
            }
            Q.all([barcodePopulate(data),
                workLocationPopulate(data)
            ]).then(function () {
                queryOperation(data[0].BarcodeMaster.ItemMaster, data[0].WorkLocation._id).then(function (operation) {
                    var num = operation.IsTiming ? 2 : 1;
                    if (flg) {//选择部门的下级有产线,需要返回A组B组之类
                        var o = {};
                        _.forEach(data, function (obj) {
                            if (obj.count >= num && obj.BarcodeMaster) {
                                if (!o[obj.BarcodeMaster.ItemMasterCode]) {
                                    o[obj.BarcodeMaster.ItemMasterCode] = {};
                                }
                                if (!o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Department.Code]) {
                                    o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Department.Code] = 1;
                                } else {
                                    o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Department.Code] += 1;
                                }
                            }
                        });
                        deferred.resolve(o);
                    } else {//选择部门的下级没有产线,需要返回用户
                        var o = {};
                        _.forEach(data, function (obj) {
                            if (obj.count >= num && obj.BarcodeMaster) {
                                if (!o[obj.BarcodeMaster.ItemMasterCode]) {
                                    o[obj.BarcodeMaster.ItemMasterCode] = {};
                                }
                                if (!o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Code]) {
                                    o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Code] = 1;
                                } else {
                                    o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Code] += 1;
                                }
                            }
                        });
                        deferred.resolve(o);
                    }
                }, function (err) {
                    deferred.reject(er);
                });
            }, function (error) {
                deferred.reject(error);
            });
        });
    });
    return deferred.promise;
}

function queryOperation (itemMaster, workLocation) {
    var deferred = Q.defer();

    stationWorkController.findByWorkLocationID(workLocation, function (err, record) {
        if (err) {
            deferred.reject(err);
            return;
        }
        if (!record || record.length === 0) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询作业错误';
            newErr.message = '工位未绑定作业';
            deferred.reject(err);
            return;
        }
        operationController.findByItemMasterAndWork(itemMaster, record[0].Work._id, function (err, operation) {
            if (err) {
                deferred.reject(err);
                return;
            }
            deferred.resolve(operation);
        });
    });

    return deferred.promise;
}

function getTotalCount(flg, locationArr, startTime, endTime) {
    var deferred = Q.defer();

    var entity = entityCollection.getEntity("BizRecord");
    var args = [];
    args.push({
        $match: {
            CreatedOn: {$gt: startTime, $lte: endTime},
            WorkLocation: {$in: locationArr}
        }
    });
    args.push({$sort: {CreatedOn: 1}});
    args.push({$group: {_id: {BarcodeMaster: "$BarcodeMaster", WorkLocation: "$WorkLocation"}, count: {$sum: 1}}});
    args.push({
        $project: {
            BarcodeMaster: "$_id.BarcodeMaster",
            WorkLocation: "$_id.WorkLocation",
            count: 1,
            _id: 0
        }
    });
    entity.aggregate(args, function (er, data) {
        if (er) {
            deferred.reject(er);
            return;
        }
        Q.all([barcodePopulate(data),
            workLocationPopulate(data)
        ]).then(function () {
            if (flg) {//选择部门的下级有产线,需要返回A组B组之类
                var o = {}, temp = {};
                _.forEach(data, function (obj) {
                    if (obj.BarcodeMaster) {
                        if (!o[obj.BarcodeMaster.ItemMasterCode]) {
                            o[obj.BarcodeMaster.ItemMasterCode] = {};
                        }
                        if (!temp[obj.BarcodeMaster.Barcode]) {
                            if (!o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Department.Code]) {
                                o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Department.Code] = 1;
                            } else {
                                o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Department.Code] += 1;
                            }
                            temp[obj.BarcodeMaster.Barcode] = true;
                        }
                    }
                });
                deferred.resolve(o);
            } else {//选择部门的下级没有产线,需要返回用户
                var o = {};
                _.forEach(data, function (obj) {
                    if (obj.BarcodeMaster) {
                        if (!o[obj.BarcodeMaster.ItemMasterCode]) {
                            o[obj.BarcodeMaster.ItemMasterCode] = {};
                        }
                        if (!o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Code]) {
                            o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Code] = 1;
                        } else {
                            o[obj.BarcodeMaster.ItemMasterCode][obj.WorkLocation.Code] += 1;
                        }
                    }
                });

                deferred.resolve(o);
            }
        }, function (error) {
            deferred.reject(error);
        });
    });
    return deferred.promise;
}
function getDepartmentByParentDepartment(parentDepartment) {
    var deferred = Q.defer();
    departmentController.getDepartmentByParentDepartment(parentDepartment, function (err, records) {
        if (err) {
            deferred.reject(err);
        }
        deferred.resolve(records)
    });
    return deferred.promise;
}
function barcodePopulate(data) {
    var deferred = Q.defer();
    var barcodeModel = mongoose.model('BarcodeMaster');
    barcodeModel.populate(data, {path: 'BarcodeMaster'}, function (e, results) {
        if (e) {
            deferred.reject(err);
        }
        // data.BarcodeMaster = results.BarcodeMaster;

        deferred.resolve()

    });
    return deferred.promise;
}
function workLocationPopulate(data) {
    var deferred = Q.defer();
    var departmentModel = mongoose.model('WorkLocation');
    departmentModel.populate(data, {
        path: 'WorkLocation',
        populate: [
            {
                path: 'Department',
                model: 'Department'
            }]
    }, function (e, results) {
        if (e) {
            deferred.reject(err);
        }
        //data.WorkLocation = results.WorkLocation;
        deferred.resolve()

    });
    return deferred.promise;
}

//通过WareHouse和Barcode查找入库记录
exports.queryRcvRecords = function (req, res) {
    var parameter = req.body,
        WareHouseId = parameter.WareHouseId;
    rcvRecordController.queryByContainerAndWareHouse(WareHouseId, function (err, records) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        res.json({
            Data: records,
            Error: null
        });
    });
};
//通过WareHouse和Barcode查找入库记录
exports.queryRcvRecordsByContainer = function (req, res) {
    var parameter = req.body,
        ContainerId = parameter.ContainerId;
    rcvRecordController.queryByContainer(ContainerId, function (err, records) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        res.json({
            Data: records,
            Error: null
        });
    });
};
